package cloud.pangui.core.mongo.operate;


import cloud.pangui.core.mongo.element.Order;
import cloud.pangui.core.mongo.utils.SqlWhereParseUtils;


import java.util.ArrayList;
import java.util.List;

import static cloud.pangui.core.mongo.utils.SqlEleParseUtil.*;


/**
 * 使用sql进行查询
 * 将sql接续为对应的其他查询使用
 *
 * @Auther hepangui
 * @Date 2020/10/06 0001
*/
public class SqlQuery<T> extends Query {

	/**
	 * 使用Query.sqlQuery来获取
	 *
	 * @param sql
	 */
	SqlQuery(String sql) {
		this.build(sql);
	}

	/**
	 * 无任何嵌套情况下的sql语句转换query
	 * sql语句转query
	 * select xxx from t where a=1 and b=2 or c=3 group by d order by e limit 0,5
	 *
	 * @return
	 */
	public SqlQuery build(String sql) {
		String sqlCopy = sql.replaceAll("\n|\t|\r|\n\r", " ");
		String sqlUpper = sqlCopy.toUpperCase();
		if (sqlUpper.indexOf(" FROM ", sqlUpper.indexOf(" FROM ") + 1) > -1) {
			// 这是一个嵌套查询
			String innerSql = sqlCopy.substring(sqlCopy.indexOf("(") + 1, sqlCopy.lastIndexOf(")"));
			SqlQuery innerQuery = new SqlQuery(innerSql);
			this.innerQuery = innerQuery;
			sqlCopy = sqlCopy.substring(0, sqlCopy.indexOf("(")) + "_INNERTABLE_" + sqlCopy.substring(sqlCopy.lastIndexOf(")") + 1);
			sqlUpper = sqlCopy.toUpperCase();
		}


		int selectBegin = sqlUpper.indexOf("SELECT ") + "SELECT ".length();
		int fromBegin = sqlUpper.indexOf(" FROM ");
		int whereBegin = sqlUpper.indexOf(" WHERE ");
		int groupBegin = sqlUpper.indexOf(" GROUP BY ");
		int orderBegin = sqlUpper.indexOf(" ORDER BY ");
		int limitBegin = sqlUpper.indexOf(" LIMIT ");

		String selectStr = sqlCopy.substring(selectBegin, fromBegin);
		if (!selectStr.trim().equals("*")) {
			List<String> splitedEles = splitEleString(selectStr);
			this.select(parseEles(splitedEles.toArray(new String[splitedEles.size()])));
		}
		String tableStr = subStrByIndex(sqlCopy, fromBegin + " FROM ".length(), whereBegin, groupBegin, orderBegin, limitBegin);
		this.collectionName = tableStr.trim();
		if (whereBegin > -1) {
			String whereStr = subStrByIndex(sqlCopy, whereBegin + " WHERE ".length(), groupBegin, orderBegin, limitBegin);
			this.where(SqlWhereParseUtils.parseWhere(whereStr));
		}
		if (groupBegin > -1) {
			String groupStr = subStrByIndex(sqlCopy, groupBegin + " GROUP BY ".length(), orderBegin, limitBegin);
			List<String> splitedEles = splitEleString(groupStr);
			this.groupBy(parseEles(splitedEles.toArray(new String[splitedEles.size()])));
		}
		if (orderBegin > -1) {
			String orderStr = subStrByIndex(sqlCopy, orderBegin + " ORDER BY ".length(), limitBegin);
			this.orderBy(parseOrders(orderStr));
		}
		if (limitBegin > -1) {
			String limitStr = subStrByIndex(sqlCopy, limitBegin + " LIMIT ".length());
			this.parseLimits(limitStr);
		}
		return this;
	}

	/**
	 * 解析limit 100,10
	 *
	 * @param limitStr
	 */
	private void parseLimits(String limitStr) {
		if (limitStr.indexOf(",") > -1) {
			String[] split = limitStr.split(",");
			limit(toInt(split[0].trim()), toInt(split[1].trim()));
		} else {
			limit(toInt(limitStr));
		}
	}

	/**
	 * 解析排序
	 * 排序不支持函数
	 *
	 * @param orderStr
	 */
	private Order[] parseOrders(String orderStr) {
		String[] split = orderStr.split(",");
		List<Order> list = new ArrayList<>();
		for (String s : split) {
			if (s.trim().indexOf(" ") > -1) {
				String[] s1 = s.trim().split(" ");
				if ("DESC".equalsIgnoreCase(s1[1])) {
					list.add(Order.desc(s1[0]));
				} else {
					list.add(Order.asc(s1[0]));
				}
			} else {
				list.add(Order.asc(s));
			}
		}
		return list.toArray(new Order[list.size()]);

	}

	/**
	 * 截取一段，截取至indexs中不为-1的值
	 *
	 * @param str
	 * @param from
	 * @param indexs
	 * @return
	 */
	private String subStrByIndex(String str, int from, int... indexs) {
		for (int index : indexs) {
			if (index > -1) {
				return str.substring(from, index);
			}
		}
		return str.substring(from);
	}


}
